package cn.iocoder.yudao.module.digital.service.cardchannel.impl.bamboo;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.digital.enums.cardkeysecret.CardKeySourceEnum;
import cn.iocoder.yudao.module.digital.framework.cardkey.config.CardKeyConfig;
import cn.iocoder.yudao.module.digital.service.cardchannel.ICardChannel;
import cn.iocoder.yudao.module.digital.service.cardchannel.model.bamboo.*;
import cn.iocoder.yudao.module.digital.service.cardchannel.model.common.*;
import cn.iocoder.yudao.module.infra.constants.InfraHeaderConstants;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Bamboo实现
 */
@Component(value = "CardChannelBambooImpl")
@Slf4j
public class CardChannelBambooImpl implements ICardChannel {
    private static final String PATH_PRODUCT_CATALOG = "/api/integration/v2.0/catalog?PageSize=100&PageIndex=%s";
    private static final String PATH_PLACE_ORDER = "/api/integration/v1.0/orders/checkout";
    private static final String PATH_QUERY_ORDER = "/api/integration/v1.0/orders/%s";
    private static final String PREFIX_PRODUCT_ID = "Bamboo_";

    @Resource
    private CardKeyConfig cardKeyConfig;

    @Override
    public CdkGenCardResult createAggregatedOrder(CdkGenCardReq req) {
        return createMultipleQuantitiesOrder(req);
    }

    @Override
    public CdkGenCardResult createSingleQuantitiesOrder(CdkGenCardReq req) {
        return createMultipleQuantitiesOrder(req);
    }

    @Override
    public CdkGenCardResult createMultipleQuantitiesOrder(CdkGenCardReq req) {
        // requestId使用卡密订单id, 防止重复创建订单
        final String cardOrderId = req.getCardOrderId();
        log.info("Bamboo创建卡密订单-开始, cardOrderId = {}", cardOrderId);

        // 生成订单
        final BambooGenCardKeyOrderRes genCardKeyOrderRes = genCardKeyOrderWithRetry(cardOrderId, req);
        final String bambooOrderId = genCardKeyOrderRes.getBambooOrderId();
        if (genCardKeyOrderRes.getOrderStatus() != CdkOrderStatusEnum.SUBMIT_SUCCESS || StrUtil.isEmpty(bambooOrderId)) {
            final CdkGenCardResult cardResult = CdkGenCardResult.builder()
                    .orderStatus(genCardKeyOrderRes.getOrderStatus())
                    .errorMsg(genCardKeyOrderRes.getErrorMsg())
                    .build();
            log.warn("Bamboo创建卡密订单-失败, cardOrderId = {}, cardResult = {}",
                    cardOrderId, JsonUtils.toJsonString(cardResult));
            return cardResult;
        }

        // 查询订单
        final CdkGenCardResult cardResult = queryOrder(cardOrderId, bambooOrderId);

        log.info("Bamboo创建卡密订单-成功, cardOrderId = {}, cardResult = {}",
                cardOrderId, JsonUtils.toJsonString(cardResult));
        return cardResult;
    }

    private BambooGenCardKeyOrderRes genCardKeyOrderWithRetry(String cardOrderId, CdkGenCardReq genCardReq) {
        final String requestId = IdUtil.fastSimpleUUID();
        BambooGenCardKeyOrderRes res = null;
        for (int i = 0; i < 3; i++) {
            if (i > 0) {
                // 间隔 1000ms下单
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            }

            res = genCardKeyOrder(i, requestId, cardOrderId, genCardReq);
            if (res.getOrderStatus() == CdkOrderStatusEnum.SUBMIT_SUCCESS) {
                break;
            }
        }
        return res;
    }

    private BambooGenCardKeyOrderRes genCardKeyOrder(int index, String requestId, String cardOrderId, CdkGenCardReq genCardReq) {
        final String url = cardKeyConfig.getBamboo().getHost() + PATH_PLACE_ORDER;

        try {
            final BambooCreateOrderReq req = new BambooCreateOrderReq();
            req.setRequestId(requestId);
            req.setAccountId(cardKeyConfig.getBamboo().getAccountId());

            final List<BambooCreateOrderReq.Product> Products = genCardReq.getProducts().stream()
                    .map(v -> BambooCreateOrderReq.Product.builder()
                            .ProductId(parseProductId(v.getProductNo()))
                            .Quantity(v.getQuantity())
                            .Value(new BigDecimal(v.getBuyDenomination()).divide(new BigDecimal(100)).toPlainString()) // 分转换为元
                            .build())
                    .collect(Collectors.toList());
            req.setProducts(Products);
            final String reqBody = JsonUtils.toJsonString(req);

            log.info("Bamboo生成卡密-生成订单-开始, index = {}, cardOrderId = {}, url = {}, reqBody = {}",
                    index, cardOrderId, url, reqBody);
            final HttpResponse httpResponse = HttpRequest.post(url)
                    .basicAuth(cardKeyConfig.getBamboo().getUserName(), cardKeyConfig.getBamboo().getPassword())
                    .header(InfraHeaderConstants.HEADER_BUSINESS_ID, cardOrderId)
                    .body(reqBody)
                    .execute();
            if (httpResponse.isOk()) {
                final String responseBody = httpResponse.body();
                final String bambooOrderId = extractValueBetweenQuotes(responseBody);
                log.info("Bamboo生成卡密-生成订单-成功, index = {}, cardOrderId = {}, url = {}, bambooOrderId = {}, responseBody = {}",
                        index, cardOrderId, url, bambooOrderId, responseBody);
                return BambooGenCardKeyOrderRes.builder().orderStatus(CdkOrderStatusEnum.SUBMIT_SUCCESS).bambooOrderId(bambooOrderId).build();
            } else {
                final BambooBaseResponse baseResponse = parseBambooBaseResponse(url, httpResponse);
                final String errorMsg = getErrorMsg("生成卡密", httpResponse.getStatus(), baseResponse);
                log.error("Bamboo生成卡密-生成订单-失败, index = {}, cardOrderId = {}, url = {}, errorMsg = {}, responseBody = {}",
                        index, cardOrderId, url, errorMsg, httpResponse.body());
                return BambooGenCardKeyOrderRes.builder().orderStatus(CdkOrderStatusEnum.SUBMIT_FAILURE).errorMsg(errorMsg).build();
            }
        } catch (Exception e) {
            final String errorMsg = StrUtil.format("Bamboo生成卡密-生成订单-异常, index = {}, requestId = {}, cardOrderId = %s",
                    index, requestId, cardOrderId);
            log.error(errorMsg, e);
            return BambooGenCardKeyOrderRes.builder().orderStatus(CdkOrderStatusEnum.SUBMIT_EXCEPTION).errorMsg(errorMsg).build();
        }
    }

    @Override
    public CdkGenCardResult queryOrder(String cardOrderId, String channelOrderId) {
        final BambooGenCardResult bambooResult = queryCardKeySecretOrder(cardOrderId, channelOrderId);
        final CdkGenCardResult cardResult = toCdkGenCardResult(bambooResult, channelOrderId);
        return cardResult;
    }

    private CdkGenCardResult toCdkGenCardResult(BambooGenCardResult genCardResult, String bambooOrderId) {
        final List<CdkCardSecret> cardSecrets = new ArrayList<>();

        if (genCardResult.getOrderDetail() != null && CollUtil.isNotEmpty(genCardResult.getOrderDetail().getItems())) {
            for (BambooOrderDetail.Item item : genCardResult.getOrderDetail().getItems()) {
                if (CollUtil.isNotEmpty(item.getCards())) {
                    for (BambooOrderDetail.Card card : item.getCards()) {
                        final BambooCardStatusEnum cardStatusEnum = BambooCardStatusEnum.fromValue(card.getStatus());
                        if (cardStatusEnum == BambooCardStatusEnum.Sold) {
                            final CdkCardSecret cdkSecret = createCdkSecret(item, card);
                            cardSecrets.add(cdkSecret);
                        }
                    }
                }
            }
        }

        String channelInnerOrderId = null;
        if (genCardResult.getOrderDetail() != null && genCardResult.getOrderDetail().getOrderId() != null) {
            channelInnerOrderId = genCardResult.getOrderDetail().getOrderId().toString();
        }

        final CdkGenCardResult cardResult = CdkGenCardResult.builder()
                .channelCardOrderId(bambooOrderId)
                .channelInnerOrderId(channelInnerOrderId)
                .orderStatus(genCardResult.getOrderStatus())
                .errorMsg(genCardResult.getErrorMsg())
                .cards(cardSecrets)
                .build();
        return cardResult;
    }

    private CdkCardSecret createCdkSecret(BambooOrderDetail.Item item, BambooOrderDetail.Card card) {
        final CdkCardSecret cdkSecret = new CdkCardSecret();

        cdkSecret.setCardDetailData(JsonUtils.toJsonString(card));

        final String productNo = genProductNo(item.getProductId());
        cdkSecret.setProductNo(productNo);
        cdkSecret.setCurrencyCode(item.getCurrencyCode());
        cdkSecret.setBuyDenomination(item.getProductFaceValue().multiply(new BigDecimal(100)).intValue());

        cdkSecret.setEGiftId(String.valueOf(card.getId()));
        cdkSecret.setCardNumber(card.getSerialNumber()); // (Card) Serial Number
        cdkSecret.setCode(card.getCardCode()); // Redeem Code
        cdkSecret.setPin(card.getPin()); // Security Pin of an Account
        return cdkSecret;
    }

    private BambooGenCardResult queryCardKeySecretOrder(String cardOrderId, String bambooOrderId) {
        final String url = String.format(cardKeyConfig.getBamboo().getHost() + PATH_QUERY_ORDER, bambooOrderId);
        try {
            log.info("Bamboo生成卡密-查询订单-开始, cardOrderId = {}, bambooOrderId = {}, url = {}", cardOrderId, bambooOrderId, url);

            final HttpResponse httpResponse = HttpRequest.get(url)
                    .basicAuth(cardKeyConfig.getBamboo().getUserName(), cardKeyConfig.getBamboo().getPassword())
                    .header(InfraHeaderConstants.HEADER_BUSINESS_ID, cardOrderId)
                    .execute();
            if (httpResponse.isOk()) {
                final String responseBody = httpResponse.body();
                final BambooOrderDetail orderDetail = JsonUtils.parseObject(responseBody, BambooOrderDetail.class);
                final BambooOrderStatusEnum orderStatus = BambooOrderStatusEnum.fromValue(orderDetail.getStatus());

                final List<BambooOrderDetail.Card> cards = new ArrayList<>();
                final CdkOrderStatusEnum finalStatus;
                switch (orderStatus) {
                    case Succeeded:
                        // 成功，获取卡密
                        finalStatus = CdkOrderStatusEnum.CARD_SUCCESS;
                        log.info("Bamboo生成卡密-查询订单-成功, url = {}, cardOrderId = {}, bambooOrderId = {}, cards = {}, responseBody = {}",
                                url, cardOrderId, bambooOrderId, cards, responseBody);
                        break;
                    case PartialFailed:
                        // 部分失败，获取卡密
                        finalStatus = CdkOrderStatusEnum.CARD_PARTIAL_SUCCESS;
                        log.error("Bamboo生成卡密-查询订单-部分失败, url = {}, cardOrderId = {}, bambooOrderId = {}, cards = {}, responseBody = {}",
                                url, cardOrderId, bambooOrderId, cards, responseBody);
                        break;
                    case Failed:
                        // 失败，终止
                        finalStatus = CdkOrderStatusEnum.CARD_FAILURE;
                        log.error("Bamboo生成卡密-查询订单-失败, url = {}, cardOrderId = {}, bambooOrderId = {}, cards = {}, responseBody = {}",
                                url, cardOrderId, bambooOrderId, cards, responseBody);
                        break;
                    case Created:
                    case Pending:
                    case Processing:
                    case Processed:
                        // 处理中，需要后续定时任务查询
                        finalStatus = CdkOrderStatusEnum.CARD_PROCESSING;
                        log.warn("Bamboo生成卡密-查询订单-处理中, url = {}, cardOrderId = {}, bambooOrderId = {}, cards = {}, responseBody = {}",
                                url, cardOrderId, bambooOrderId, cards, responseBody);
                        break;
                    default:
                        log.error("Bamboo生成卡密-查询订单-未知的status, url = {}, cardOrderId = {}, bambooOrderId = {}, orderStatus = {}, responseBody = {}",
                                url, cardOrderId, bambooOrderId, orderDetail.getStatus(), responseBody);
                        throw new IllegalArgumentException(String.format("未知的status = %s", orderDetail.getStatus()));
                }
                return BambooGenCardResult.builder().orderStatus(finalStatus).orderDetail(orderDetail).build();
            } else {
                final BambooBaseResponse baseResponse = parseBambooBaseResponse(url, httpResponse);
                final String errorMsg = getErrorMsg("查询订单", httpResponse.getStatus(), baseResponse);
                log.error("Bamboo生成卡密-查询订单-失败, url = {}, cardOrderId = {}, bambooOrderId = {}, errorMsg = {}, responseBody = {}",
                        url, cardOrderId, bambooOrderId, errorMsg, httpResponse.body());
                return BambooGenCardResult.builder().orderStatus(CdkOrderStatusEnum.QUERY_FAILURE).errorMsg(errorMsg).build();
            }
        } catch (Exception e) {
            log.error(StrUtil.format("Bamboo生成卡密-查询订单-失败, url = {}, cardOrderId = {}, bambooOrderId = {}",
                    url, cardOrderId, bambooOrderId), e);
            return BambooGenCardResult.builder().orderStatus(CdkOrderStatusEnum.QUERY_EXCEPTION).errorMsg(e.getMessage()).build();
        }
    }

    private static String extractValueBetweenQuotes(String input) {
        String pattern = "\"([^\"]*)\"";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(input);
        if (m.find()) {
            return m.group(1);
        } else {
            return null; // 或者抛出异常
        }
    }

    @Override
    public List<CdkProduct> getAllProducts() {
        final List<CdkProduct> allList = new ArrayList<>();
        int pageIndex = 0;
        while (true) {
            final List<CdkProduct> cdkProducts = queryProductsByPage(pageIndex);
            if (CollUtil.isEmpty(cdkProducts)) {
                break;
            }

            allList.addAll(cdkProducts);
            pageIndex++;
        }

        log.info("Bamboo查询商品-全部完成, pageIndex = {}, total = {}", pageIndex, allList.size());
        return allList;
    }

    private List<CdkProduct> queryProductsByPage(int pageIndex) {
        final String url = String.format(cardKeyConfig.getBamboo().getHost() + PATH_PRODUCT_CATALOG, pageIndex);
        log.info("Bamboo查询商品-开始, pageIndex = {}, url = {}", pageIndex, url);

        final HttpResponse httpResponse = HttpRequest.get(url)
                .basicAuth(cardKeyConfig.getBamboo().getUserName(), cardKeyConfig.getBamboo().getPassword())
                .execute();
        if (httpResponse.isOk()) {
            log.info("Bamboo查询商品-成功, pageIndex = {}, url = {}, responseBody = {}", pageIndex, url, httpResponse.body());
            final BambooCatalog catalog = JsonUtils.parseObject(httpResponse.body(), BambooCatalog.class);

            final List<CdkProduct> products = new ArrayList<>();
            for (BambooCatalog.Item item : catalog.getItems()) {
                for (BambooCatalog.Product product : item.getProducts()) {
                    final CdkProduct cdkProduct = new CdkProduct();
                    final String productNo = genProductNo(product.getId());
                    cdkProduct.setSource(CardKeySourceEnum.BAMBOO_API.getValue());
                    cdkProduct.setProductNo(productNo);
                    cdkProduct.setProductName(product.getName());
                    cdkProduct.setProductDescription(item.getDescription());
                    cdkProduct.setEntityId(String.valueOf(product.getId()));
                    cdkProduct.setItemId(item.getInternalId());
                    cdkProduct.setLocale(item.getCountryCode());
                    cdkProduct.setCurrencyCode(item.getCurrencyCode());
                    final boolean customDenomination =
                            product.getMinFaceValue().compareTo(product.getMaxFaceValue()) != 0;
                    cdkProduct.setCustomDenomination(customDenomination);
                    final int denominationMin = product.getMinFaceValue().multiply(new BigDecimal(100)).intValue();
                    cdkProduct.setDenominationMin(denominationMin);
                    final int denominationMax = product.getMaxFaceValue().multiply(new BigDecimal(100)).intValue();
                    cdkProduct.setDenominationMax(denominationMax);
                    if (!customDenomination && cdkProduct.getDenominationMin().equals(cdkProduct.getDenominationMax())) {
                        // 固定面额
                        cdkProduct.setDenominationFixed(cdkProduct.getDenominationMin());
                    }

                    cdkProduct.setImageUrls(JsonUtils.toJsonString(Arrays.asList(new BambooImg(item.getLogoUrl()))));
                    cdkProduct.setRedemptionInstructions(item.getRedemptionInstructions());
                    cdkProduct.setTerms(item.getTerms());
                    cdkProduct.setProductDetailData(JsonUtils.toJsonString(product));
                    products.add(cdkProduct);
                }
            }
            return products;
        } else {
            log.warn("Bamboo查询商品-失败, pageIndex = {}, url = {}, responseBody = {}", pageIndex, url, httpResponse.body());
            final BambooBaseResponse baseResponse = parseBambooBaseResponse(url, httpResponse);
            final String errorMsg = getErrorMsg("获取产品", httpResponse.getStatus(), baseResponse);
            throw new RuntimeException(errorMsg);
        }
    }

    private static String parseProductId(String productNo) {
        final int start = productNo.indexOf(PREFIX_PRODUCT_ID) + PREFIX_PRODUCT_ID.length();
        final String id = productNo.substring(start);
        return id;
    }

    private static String genProductNo(String productId) {
        final String productNo = PREFIX_PRODUCT_ID + productId;
        return productNo;
    }

    private BambooBaseResponse parseBambooBaseResponse(String url, HttpResponse httpResponse) {
        try {
            final BambooBaseResponse baseResponse = JsonUtils.parseObject(httpResponse.body(),
                    BambooBaseResponse.class);
            return baseResponse;
        } catch (Exception e) {
            log.warn(String.format("解析Bamboo响应失败, url = %s, responseBody = %s", url, httpResponse.body()), e);
        }
        return null;
    }

    private String getErrorMsg(String action, int statusCode, BambooBaseResponse baseResponse) {
        final String errorMsg;
        if (baseResponse != null) {
            final String errorCode = baseResponse.getStatus();
            String message = baseResponse.getMessage();
            if (StrUtil.isEmpty(message)) {
                message = baseResponse.getTitle();
            }
            if (StrUtil.isEmpty(message)) {
                message = baseResponse.getError();
            }
            errorMsg = String.format("请求Bamboo失败, action = %s, statusCode = %s, errorCode = %s, message = %s",
                    action, statusCode, errorCode, message);
        } else {
            errorMsg = String.format("请求Bamboo失败, action = %s, statusCode = %s", action, statusCode);
        }
        return errorMsg;
    }

    public static void main(String[] args) {
        writeExcel();
    }

    private static void writeExcel(){
        ObjectMapper objectMapper = new ObjectMapper();

        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
        objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化
        objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

        String jsonlFilePath = "E:/data/card/key.jsonl";
        String excelOutputPath = "E:/data/card/extracted_data.xlsx";

        // 解析 JSON Lines 文件并提取数据
        List<ExportData> exportDataList = new ArrayList<>();

        try (BufferedReader br = new BufferedReader(new FileReader(jsonlFilePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                // 每行是一个 JSON 对象
                Map<String, Object> data = objectMapper.readValue(line, Map.class);

                String requestId = (String) data.get("requestId");
                Integer orderId = (Integer) data.get("orderId");
                List<Map<String, Object>> items = (List<Map<String, Object>>) data.get("items");

                for (Map<String, Object> item : items) {
                    Integer productId = (Integer) item.get("productId");
                    BigDecimal productFaceValue = (BigDecimal) item.get("productFaceValue");
                    List<Map<String, Object>> cards = (List<Map<String, Object>>) item.get("cards");

                    for (Map<String, Object> card : cards) {
                        ExportData exportData = new ExportData();
                        exportData.setRequestId(requestId);
                        exportData.setOrderId(orderId);
                        exportData.setProductId(productId);
                        exportData.setProductFaceValue(productFaceValue.toPlainString());
                        exportData.setId((Integer) card.get("id"));
                        exportData.setCardCode((String) card.get("cardCode"));
                        exportData.setSerialNumber((String) card.get("serialNumber"));
                        exportData.setPin((String) card.get("pin"));

                        exportDataList.add(exportData);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        exportDataList.sort(new Comparator<ExportData>() {
            @Override
            public int compare(ExportData o1, ExportData o2) {
                return o1.productId.compareTo(o2.productId);
            }
        });

        // 将数据写入 Excel
        EasyExcel.write(excelOutputPath, ExportData.class)
                .sheet("Data")
                .doWrite(exportDataList);

        System.out.println("Excel 文件已生成: " + excelOutputPath);
    }

    // 定义数据模型
    @Data
    public static class ExportData {
        @ExcelProperty("requestId")
        private String requestId;

        @ExcelProperty("orderId")
        private Integer orderId;

        @ExcelProperty("id")
        private Integer id;

        @ExcelProperty("productId")
        private Integer productId;

        @ExcelProperty("productFaceValue")
        private String productFaceValue;

        @ExcelProperty("cardCode")
        private String cardCode;

        @ExcelProperty("serialNumber")
        private String serialNumber;

        @ExcelProperty("pin")
        private String pin;
    }

    private static void queryOrder() {
        List<String> lines = new ArrayList<>();

        List<String> ids = Arrays.asList(
                "d33a1017-0f42-4d84-9dda-1de95aadb87d",
                "5920ec51-28be-47ac-93fe-cf56f654b9ce",
                "97c88d73-8640-4e14-959c-c638622a952e",
                "93610a48-c4c7-4f9a-bd34-436f45a2dcb6",
                "f1509883-e17e-4e13-8119-c3d137b5c0e1",
                "018abdca-4b6a-4741-a1b5-6427f78d77d0",
                "c97d7371-03dc-4b8c-b1fd-5c855531b5ac",
                "23a62f71-221c-49a9-a67d-4487b4f5fc41",
                "0b40a4ca-05d7-4012-b223-b6bc20d6add7",
                "c7d5af4f-83bd-47cc-9f78-dc229c58b926",
                "12790e0b-6732-4944-8529-697588c55bdf",
                "011605cd-0787-4124-b11c-be686deb98e5",
                "430e8b31-827b-45fa-9588-d61eae6230c2",
                "5ff61690-2c7a-4057-9ad2-cfd90a09d5a7",
                "e3c0cf08-c1f7-4876-bd7b-187c95fdbca1",
                "e4e10a7c-7d75-4c59-986f-c620a29aab2d",
                "ece63486-8b5e-421a-bc8b-ff73c1e31da9",
                "d2d18faf-6239-46e9-89bd-334a677498cd",
                "25080592-6d5e-47d5-98ab-2aea00a25a53",
                "27b515db-632f-4b22-8071-623716eb294d",
                "d5c43efe-221c-4f50-a701-823070e14411",
                "d970181a-dbc8-4ce1-8666-ad0cc28c7cbf",
                "3652c584-919a-4033-870c-7726aee3219a",
                "2b3c455b-111b-4937-b596-2cfe96cbd797",
                "dacbd160-337e-47a6-b418-82aaa56eceb1",
                "227a6327-df24-4b49-9423-7c3b43caf26f",
                "11d22b5e-0edd-40d8-949c-e97bf11f8164",
                "c1ec4feb-5f5a-437b-9b9f-082b3f623cbc",
                "7730cf10-3366-4a9f-9a9d-219a5c35c19d",
                "376d70bf-1415-4a8c-9fb9-a6f317fc4203",
                "2ff0af59-047b-4a10-a449-b11b1fe80207",
                "e9741447-a7be-4e62-97c2-0c6b1365d22c",
                "64cd0085-43f4-4e7b-a2a8-2f3f4ae99745",
                "8441e3d0-30fc-43b0-87cb-01516be4cda2",
                "81cd7b15-b87c-484d-b5f5-072becb0ff04",
                "94d1a606-f990-4772-9b1b-7b45af0ce4c6",
                "06b9f68e-9890-4a06-b972-c8c9ba6d8e6c",
                "075fc6be-3db4-4e8f-bc6c-10f8af21dbe3",
                "1cad573e-6b4d-4ec8-8e4b-465a43a94208",
                "c86b5ae1-3655-4f88-a617-9f91d288cc47",
                "a8570219-a7a9-4e1c-849e-68788e5ad6c2",
                "179f4c23-7eab-4447-b445-f4e7a901e124",
                "d86af7f0-4c7b-44a1-859c-4c9b85362c1a",
                "82462acb-dfe5-4dba-8899-4f8f09f452c9",
                "4a4716f3-5c54-4c27-9360-92ebdc2d0329"
        );

        for (String id : ids) {
            final String url = "https://api.bamboocardportal.com/api/integration/v1.0/orders/" + id;
            final HttpResponse httpResponse = HttpRequest.get(url)
                    .basicAuth("EPAYMENTS---API", "e8263ef3-010e-4c3e-a4ab-ada7709d4a71")
                    .execute();
            System.out.println(httpResponse.getStatus());
            System.out.println(httpResponse.body());

            lines.add(httpResponse.body());
        }

        FileUtil.writeUtf8Lines(lines, "E:/data/card/key.jsonl");
    }

}
